﻿using Microsoft.Win32;
using NhWeather.IO;
using NhWeather.Modbus;
using NhWeather.nModbusDevice;
using NhWeather.Register;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel.Design;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using Windows.Storage.Streams;

namespace NhWeather.Service;

class CommunicationService : IIOListener
{
    /// <summary>
    /// 虚拟485设备
    /// </summary>
    public List<DataRecorder> DataRecorders { get; set; } = [];

    public SPIO Spio { get; set; }

    private CommunicationService()
    {
        Spio = new();
        Spio.SetIOListener(this);
    }

    /// <summary>
    /// 处理接受数据
    /// </summary>
    /// <param name="byts"></param>
    void IIOListener.Received(byte[] byts)
    {
        FrameValid frame = new(byts);
        
        if (!frame.IsValid) { return; } //非法帧

        if (frame.Address != 0)
        {
            var dataRecorder = DataRecorders.FirstOrDefault(dr => dr.DeviceAddress == frame.Address);
            if (dataRecorder == null)
            {   //未找到设备，新建设备
                Application.Current.Dispatcher.Invoke(() =>
                {   // 使用 Dispatcher 调度到 UI 线程
                    var controlDevcie = new ControlDevcie(frame.Address);
                    MainWindow.Instance.DeviceContainer.Children.Add(controlDevcie);
                });
            }
        }
        else if (DataRecorders.Count == 0)
        {   //命令地址为0，且没有设备
            Application.Current.Dispatcher.Invoke(() =>
            {   // 使用 Dispatcher 调度到 UI 线程
                var controlDevcie = new ControlDevcie(8);
                MainWindow.Instance.DeviceContainer.Children.Add(controlDevcie);
            });
        }

        Parallel.ForEach(DataRecorders, dr =>
        {
            var sendByts = dr.RevcieveData(byts);
            if (sendByts != null)
            {
                Spio.Send(sendByts);
            }
        });
    }

    #region 单例
    /// <summary>
    /// 单例实例,使用 Lazy<T> 类型来实现线程安全
    /// </summary>
    private static readonly Lazy<CommunicationService> _instance = new(() => new CommunicationService());

    /// <summary>
    /// 获取单例实例
    /// </summary>
    public static CommunicationService Instance => _instance.Value;
    #endregion
}
